前后端分离

您所在的位置:网站首页 vue spring boot 上传文件 前后端分离

前后端分离

#前后端分离 | 来源: 网络整理| 查看: 265

前后端分离 – 深入浅出系列 Spring Boot + Vue + ElementUI 实现相册管理系统【文件上传 分页 】 文件上传也不过如此~ 引言

Hello,我是Bug终结者,一名热爱后端Java的风趣且幽默的程序员~ 终于等到幸运的你~

快来发现我的宇宙哦~

博文系列

深入浅出前后端分离系列第一篇:前后端分离 — 深入浅出Spring Boot + Vue实现员工管理系统 Vue如此简单~

项目简介

开发一个基于Spring Boot + Vue的前后端分离相册管理系统项目,完成增、删、改、列表、多条件、分页的功能

功能细节:

实现照片的新增、删除、修改、列表、多条件、分页图片上传使用 el-upload 控件,建议设置 auto-upload 为 false。控制图片最大不能超过5M上传的必须是图片,或者约束后缀为 png/jpg/gif/bmp等图片。建议先保存标题信息到数据库,并返回得到noid的值,然后再上传图片,并更新 relative_path字段。图片保存文件命名为 yyyyMMdd/HHmmssXXXX.后缀这样的图片,例如图片为 仓鼠.png,保存后类似为 20220107/1115232832.png, XXXX表示4位的随机数字。图片在列表上显示为 200X200大小列表要支持分页,分页控件使用 el-pagination删除的时候,要将图片从硬盘上删除掉,然后再删除数据库中的记录。列表页显示如下 在这里插入图片描述 效果图

在这里插入图片描述

开发环境

后端:Spring Boot + MyBatis + Maven

前端:Vue + ElementUI

工具:前端使用WebStorm,后端使用IDEA

放松一下~

在这里插入图片描述

适度适度~

在这里插入图片描述

挺解乏的哦~🥰

言归正传~

项目风格

请求方式统一为Post请求,目的是保证安全性

规范了接口层统一返回格式为ResultBean,详细如:

统一返回格式风格类,ResultBean

状态码,详细信息,数据

数据表

t_picture

CREATE TABLE `t_picture` ( `noid` int(11) NOT NULL AUTO_INCREMENT, `picture_name` varchar(64) NOT NULL COMMENT '照片名称', `relative_path` varchar(128) DEFAULT NULL COMMENT '存储相对路径', `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', PRIMARY KEY (`noid`) ) ENGINE=InnoDB AUTO_INCREMENT=71 DEFAULT CHARSET=utf8mb4 项目结构 前端结构

在这里插入图片描述

后端结构

在这里插入图片描述

项目难点

前端部分难点:

上传文件采用elementui控件的el-upload,要求不可自动上传,所以设置自动上传为false

其中,要先保存数据到数据库在进行保存图片路径存入数据库,通过存入的数据id去修改当前的数据

显示图片时采用了provide / inject组合控制的显示

因为上传成功后需要再次刷新,如果不刷新,图片不出来,那就要重新刷新页面,但刷新页面对用户来说极不友好,而且时间慢,效率低,所以采用该显示方式,完美解决了二次加载的问题

介绍provide / inject组合控制的显示到底怎么用

首先在app.vue中加入如下代码

app.vue

export default { name: 'App', computed: {}, watch: {}, //加入provide provide() { return{ //返回reload方法,该方法为全局方法 reload: this.reload, } }, data() { return { isRouteAlive:true }; }, methods: { //刷新页面 reload() { this.isRouteAlive = false; this.$nextTick(function () { this.isRouteAlive = true; }) } } }; @import '//at.alicdn.com/t/font_2048717_67mh6lqgbh.css';

在要二次加载的vue文件中加入provide

在这里插入图片描述

执行完上传图片代码后,进行二次加载 在这里插入图片描述

完美解决二次加载

核心源码 前端源码

PictureList.vue

搜索 新增 修改 删除 选取文件 只能上传png/jpg/gif/bmp文件,且不超过5M 确定 取消 import request from '@/common/utils/request'; export default { computed:{ }, inject: ['reload'], data() { return { searchInfo: {searchKey:''}, picturePage:{pageNum: 1, pageSize: 2, list: []}, showPictureDigLog:false, picture:{}, uploadUrl:'', uploadDataParam:{}, src_url:'http://127.0.0.1:8345/springbootajax/', editPicture:false, }; }, watch:{ '$route.path':{ handler:function(newVal){ if(newVal == '/picture-list'){ this.initData(); } }, immediate: true }, }, mounted() { this.uploadUrl = this.settings.apiUrl + "/picture/upload"; this.initData(); }, methods: { initData() { this.getPictureList(); }, getPictureList() { let url = this.settings.apiUrl + "/picture/page"; let data = {}; data.searchKey = this.searchInfo.searchKey; data.pageNum = this.picturePage.pageNum; data.pageSize = this.picturePage.pageSize; console.log(data) request.post(url, data).then((res) => { if (res.code === 0) { this.picturePage = res.data; } }) }, clkBtnAdd(){ this.picture = {}; this.showPictureDigLog = true; }, clkBtnEdit(row) { this.picture = JSON.parse(JSON.stringify(row)); this.editPicture = true; this.showPictureDigLog = true; }, checkFileType(file) { let imgSize = file.size / 1024 / 1024; console.log("文件类型:"+file.type); console.log("文件大小:" + imgSize) if (imgSize > 5) { this.$message("文件超出规定上传大小,请重新上传文件!") return false; } //png/jpg/gif/bmp }, clkBtnSave() { let url = this.settings.apiUrl + "/picture/save"; let data = this.picture; request.post(url, data).then((res) => { if (res.code === 0) { this.uploadDataParam.noid = res.data; this.submitUpload(); this.showPictureDigLog = false; this.getPictureList(); this.$message("保存成功~") } }) }, //保存表单提交 submitUpload() { this.$refs.upload.submit(); this.reload(); }, clkBtnDelete(row) { this.$confirm("您确信要删除吗?", "提示").then(() => { let url = this.settings.apiUrl + "/picture/delete"; let data = {noid: row.noid}; request.post(url, data).then((res) => { if (res.code === 0) { this.getPictureList(); this.$message("删除成功~"); } }) }).catch(() => { this.$message("取消删除~"); }) }, chgPageNum(pageNum) { this.picturePage.pageNum = pageNum; this.getPictureList(); }, clkBtnSearch() { this.getPictureList(); } }, }; .box-main2 { width: 90%; margin: 10px; box-table2{ height: auto; } .box-search{ display: flex; margin: 10px; .m1{ padding-left: 10px; } } .box-page1{ margin-top: 10px; } } 添加路由

route.js

{ path: '/picture-list', meta: {pageTitle: '相册管理', leftMenuIndex: 'picture-list'}, component: () => import('@/views/PictureList') }, 添加左侧菜单显示

LeftMenu.vue

相册列表 后端源码

PictureController

package com.wanshi.controller; import com.github.pagehelper.PageInfo; import com.wanshi.bean.Picture; import com.wanshi.bean.ResultBean; import com.wanshi.service.PictureService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; import java.util.List; import java.util.Map; @RestController @CrossOrigin @RequestMapping("/picture") public class PictureController { @Autowired private PictureService pictureService; /** * 相册分页 * @param param * @return */ @PostMapping("/page") public ResultBean page(@RequestBody Picture param) { ResultBean res = pictureService.page(param); return res; } /** * 保存,将新增和修改合成了一个方法,根据id判断是新增或修改 * @param param * @return */ @PostMapping("/save") public ResultBean insert(@RequestBody Picture param) { ResultBean res = pictureService.save(param); return res; } /** * 删除图片 * @param param * @return */ @PostMapping("/delete") public ResultBean delete(@RequestBody Picture param) { ResultBean res = pictureService.delete(param); return res; } /** * 上传图片,与上传信息分开,改为手动上传,点击确定后,先保存数据,再保存图片相关信息至数据库 * @param map * @param file * @return */ @PostMapping("/upload") public ResultBean upload(@RequestParam Map map, MultipartFile file) { ResultBean res = pictureService.upload(map, file); return res; } }

PictureService

package com.wanshi.service; import com.github.pagehelper.PageHelper; import com.github.pagehelper.PageInfo; import com.wanshi.bean.Picture; import com.wanshi.bean.ResultBean; import com.wanshi.config.GlobalSet; import com.wanshi.mapper.PictureMapper; import com.wanshi.utils.PbFileUtils; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.web.multipart.MultipartFile; import java.io.File; import java.text.SimpleDateFormat; import java.util.List; import java.util.Map; @Service public class PictureService { @Autowired private GlobalSet globalSet; @Autowired private PictureMapper pictureMapper; private SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日"); public ResultBean page(Picture param) { PageHelper.clearPage(); PageHelper.startPage(param.getPageNum(), param.getPageSize()); List pictureList = pictureMapper.list(param); for (Picture picture : pictureList) { if (picture != null) { picture.setStrCreateTime(sdf.format(picture.getCreate_time())); } } PageInfo pageInfo = new PageInfo(pictureList); return ResultBean.create(0, "success", pageInfo); } public ResultBean save(Picture param) { if (param.getNoid() != null ) { pictureMapper.update(param); } else { pictureMapper.insert(param); } return ResultBean.create(0, "success", param.getNoid()); } public ResultBean delete(Picture param) { //获取要删除的照片存储相对地址 Picture picture = pictureMapper.get(param); //拼接绝对路径并删除 new File(globalSet.getUploadPath() + picture.getRelative_path()).delete(); pictureMapper.delete(param); return ResultBean.create(0, "success", null); } public ResultBean upload(Map map, MultipartFile file) { try { //查询当前id是否存在,并上传过图片 Picture picture2 = new Picture(); picture2.setNoid(Integer.valueOf((String)map.get("noid"))); Picture picture3 = pictureMapper.get(picture2); if (picture3.getRelative_path() != null) { //拼接绝对路径并删除 new File(globalSet.getUploadPath() + picture3.getRelative_path()).delete(); } //上传文件,获得上传后的文件名称 String uploadName = PbFileUtils.upload(file, globalSet.getUploadPath()); if (!StringUtils.isEmpty((String)map.get("noid"))) { Picture picture = new Picture(); picture.setNoid((Integer.valueOf((String) map.get("noid")))); picture.setRelative_path(uploadName); pictureMapper.updateImg(picture); } } catch (Exception e) { e.printStackTrace(); } return ResultBean.create(0, "success", null); } }

工具类PbFileUtils

package com.wanshi.utils; import com.wanshi.config.GlobalSet; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.web.multipart.MultipartFile; import java.io.File; import java.io.IOException; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Random; /** * 图片上传类 */ public class PbFileUtils { /** * 文件上传, * @param file 上传文件 * @param uploadPath 要上传到的路径 * @return * @throws IOException */ public static String upload(MultipartFile file, String uploadPath) throws IOException { String finalFileName = ""; if (file.getSize() > 0) { String originalFilename = file.getOriginalFilename(); //获取源文件的后缀名 String extName = originalFilename.substring(originalFilename.lastIndexOf(".")); //获取年月 SimpleDateFormat sdfYyyyMMdd = new SimpleDateFormat("yyyy-MM"); finalFileName = sdfYyyyMMdd.format(new Date()) + "/"; //获取日 SimpleDateFormat sdfdd = new SimpleDateFormat("dd"); finalFileName += sdfdd.format(new Date()) + "/"; //获取时分秒 SimpleDateFormat sdfHHmmss = new SimpleDateFormat("HHmmss"); finalFileName += sdfHHmmss.format(new Date()); //生成4位随机数字 Integer rndNum = new Random().nextInt(1000)+9000; //拼接随机数字和后缀名 finalFileName += rndNum + extName; //目标文件 File f1 = new File(uploadPath+finalFileName); if (!f1.exists()) { f1.mkdirs(); } //开始上传 file.transferTo(f1); } return finalFileName; } } 博主寄语

至此,系统到此完美结束,该案例通俗易懂,详细一步步带入,通过本案例,可提高你的学习能力以及训练自己的逻辑思维能力,认真学习的你很耀眼,相信你的技术一定会有一个质的飞跃,加油,努力练习,祝你成为你想要成为的人!

若在本项目中遇到技术难题,可在下方评论区留言或私信我,授人以鱼不如授人以渔

如果你觉得博主写的不错的话,不妨给个一键三连,点击下方小拳头即可一键三连。

点击拳头哦

转载自CSDN-专业IT技术社区

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

原文链接:https://blog.csdn.net/weixin_45526437/article/details/122395308



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3